package cs2340.g21.wms;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.LinkedList;
import java.util.List;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.provider.Settings;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.text.TextUtils;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;

public class CreateItemActivity extends WMSActivity {
    
	private static final String LOG_TAG = "debugger";
    // values that correspond to the attributes of an Item
	private String mName;
    private SerializableBitmap mPicture;
    private SerializableLocation mLocation;
    private String mDescription;
    private List<String> mTags;
    private Category mCategory = Category.LOST;
    private Calendar mDate;
    
    // UI references
    private EditText mNameView;
    private EditText mDescriptionView;
    private EditText mTagsView;
    private TextView mLocationView;
    private ImageView mPhotoView;
    
    // Location references
    private LocationManager locationManager;
    private boolean gpsEnabled;
    private Geocoder geocoder;
    
    // Picture options
    private String[] pictureOptions = {"Take picture with camera", 
    		"Choose photo from gallery"};
    private int selectedPictureOption = 0;
    private static final int CAMERA_REQUEST = 100;
    private static final int REQ_CODE_PICK_IMAGE = 200;
	
    private Coordinator coordinator;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        
        coordinator = new Coordinator();
        if(getIntent().getExtras() != null){
            coordinator = (Coordinator) getIntent().getExtras().getSerializable("cs2340.g21.wms.coordinator");
        }
        
        setContentView(R.layout.activity_create_item);
        
        initializeUI();
        
        // set up location services
        locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
        gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        
        
        // check if the view has converted
        /*
        if (mLocation != null) {
        	try {
    			// get the address from the location
	    		List<Address> addresses = geocoder.getFromLocation(
	    				mLocation.getLatitude(), mLocation.getLongitude(), 1);
	    		if (addresses != null && !addresses.isEmpty()) {
	    			// get the general location
	    			Address address = addresses.get(0);
		    		mLocationView.setText(address.getLocality());
		    		//Log.i(LOG_TAG, "Changed Location");
	    		}
	    		else {
		    		mLocationView.setText("Location not found");
		    		//Log.i(LOG_TAG, "Changed Location");
		    	}
    		}
    		catch (IOException e) {
    			Log.d("Demo", "IOException");
    		}
        }
        
        if (mPicture != null) {
        	mPhotoView.setImageBitmap(mPicture.getBitmap());
        }
        */

        
        
    }
    
    public void initializeUI() {
    	// set up create item form
        this.mNameView = (EditText) findViewById(R.id.item_name);
        this.mDescriptionView = (EditText) findViewById(R.id.item_description);
        this.mTagsView = (EditText) findViewById(R.id.item_tags);
        this.mLocationView = (TextView) findViewById(R.id.location_text);
        this.mPhotoView = (ImageView) findViewById(R.id.uploaded_photo);
        
        if (mLocation != null) {
        	mLocationView.setText(mLocation.getLocality());
        }
        if (mPicture != null) {
        	mPhotoView.setImageBitmap(mPicture.getBitmap());
        }
        
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.activity_create_item, menu);
        return true;
    }
    
    public void updateCategory(View view) {
    	switch (view.getId()) {
    		case R.id.lost_radio:
    			mCategory = Category.LOST;
    			break;
    		case R.id.found_radio:
    			mCategory = Category.FOUND;
    			break;
    		case R.id.donation_radio:
    			mCategory = Category.DONATE;
    			break;
    	}
    }
    
    public void findLocation(View view) {
        // alert dialog that requests that the user enable the location services, 
    	// then when the user clicks the "OK" button, calls enableLocationSettings()
		AlertDialog.Builder gpsOk = new AlertDialog.Builder(CreateItemActivity.this);
        gpsOk.setTitle(R.string.gps_ok);
        gpsOk.setCancelable(true);
        gpsOk.setPositiveButton(R.string.prompt_confirm, new DialogInterface.OnClickListener() {
        	public void onClick(DialogInterface dialog, int id) {
        		if (!gpsEnabled) {
        			enableLocationSettings();
        			gpsEnabled = true;
        		}
        		geocoder = new Geocoder(CreateItemActivity.this);
        		LocationProvider provider = locationManager.getProvider(LocationManager.GPS_PROVIDER);
        		if (provider!= null) {
        			mLocation = new SerializableLocation();
        			LocationListener locationListener = new LocationListener() {
        			    @Override
        			    public void onLocationChanged(Location location) {
        			        // A new location update is received
        			    	// Update mLocation
        			    	if (location != null) {
        			    		mLocation.setLocation(location);
        			    	}
    			    		else {
    			    			mLocation.setLocation(locationManager.getLastKnownLocation(
        			    				LocationManager.GPS_PROVIDER));
    			    		}
    			    		try {
    			    			// get the address from the location
        			    		List<Address> addresses = geocoder.getFromLocation(
        			    				location.getLatitude(), location.getLongitude(), 1);
        			    		if (addresses != null && !addresses.isEmpty()) {
        			    			// get the general location
        			    			Address address = addresses.get(0);
	        			    		mLocationView.setText(address.getLocality());
	        			    		mLocation.setLocality(address.getLocality());
	        			    		//Log.i(LOG_TAG, "Changed Location");
        			    		}
        			    		else {
            			    		mLocationView.setText("Location not found");
            			    		//Log.i(LOG_TAG, "Changed Location");
            			    	}
    			    		}
    			    		catch (IOException e) {
    			    			Log.d("Demo", "IOException");
    			    		}
        			    }

						@Override
						public void onProviderDisabled(String arg0) {}

						@Override
						public void onProviderEnabled(String provider) {}

						@Override
						public void onStatusChanged(String provider, int status, Bundle extras) {}
        			};
        			
        			locationManager.requestLocationUpdates(
        					// update location for at least 2 minutes while the create item form is active
        	                LocationManager.NETWORK_PROVIDER, 10000, 0, locationListener);
        		}
        	}
        });
        
        AlertDialog gpsDialog = gpsOk.create();
        gpsDialog.show();
    }
    
    public void uploadPicture(View view) {
    	AlertDialog.Builder uploadMenu = new AlertDialog.Builder(CreateItemActivity.this);
        uploadMenu.setTitle(R.string.picture_popup);
        uploadMenu.setSingleChoiceItems(pictureOptions, selectedPictureOption, 
        		new DialogInterface.OnClickListener(){
            public void onClick(DialogInterface dialog, int choice){
                if(choice == 0){
                    selectedPictureOption = 0;
                }else if(choice == 1){
                    selectedPictureOption = 1;
                }
            }
        });

        uploadMenu.setNegativeButton(R.string.action_cancel, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
            }
        });
        uploadMenu.setPositiveButton(R.string.prompt_confirm, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int id) {
                if (selectedPictureOption == 0) {
                	takePicture(CAMERA_REQUEST);
                }
                else {
                	Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
                	photoPickerIntent.setType("image/*");
                	startActivityForResult(photoPickerIntent, REQ_CODE_PICK_IMAGE);  
                }
            }
        });
        AlertDialog uploadDialog = uploadMenu.create();
        uploadDialog.show();
    }
    
    /**
     * Starts the camera application
     * 
     * @param actionCode
     */
    private void takePicture(int actionCode) {
    	if (isIntentAvailable(getApplicationContext(), MediaStore.ACTION_IMAGE_CAPTURE)) {
    		Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
            startActivityForResult(takePictureIntent, actionCode);
    	}
    }
    
    public void createItem(View view) {
    	// reset errors
    	mNameView.setError(null);
    	
    	// store values when the user presses save
    	mName = mNameView.getText().toString();
    	mDescription = mDescriptionView.getText().toString();
    	mTags = new LinkedList<String>();
    	addToTags(mTagsView.getText().toString());
    	mDate = Calendar.getInstance();
    	
    	
    	boolean cancel = false;
        View focusView = null;
    	
    	// check if the item name is valid
    	if (TextUtils.isEmpty(mName)) {
    		mNameView.setError(getString(R.string.error_field_required));
    		focusView = mNameView;
    		cancel = true;
    	}
    	
    	if (cancel) {
    		// There was an error; don't attempt to create new item and focus the first
            // form field with an error.
    		focusView.requestFocus();
    	}
    	else {
    		// Create a new item and add it to the item list

	        Item item = new Item(mName, mPicture, mLocation, mDescription, mTags, mCategory, mDate, coordinator.getUser().getId());
	        coordinator.addItem(item);

	        //Log.d(LOG_TAG, coordinator.checkMatch(item));
	        //Log.d(LOG_TAG, "year: " + mDate.YEAR);
	        //Log.d(LOG_TAG, "day: " + mDate.DAY_OF_MONTH);
	        Intent intent = new Intent();
            Filter f = new Filter(coordinator.getUser().getItems());
            ArrayList<Item> i = (ArrayList<Item>) coordinator.getUser().getItems();
            if(mCategory == Category.LOST){
                i = (ArrayList<Item>) f.lostFilter();
            }
            if(mCategory == Category.FOUND){
                i = (ArrayList<Item>) f.foundFilter();
                //Log.d(LOG_TAG, "Cat: F");
            }
            if(mCategory == Category.DONATE){
                i = (ArrayList<Item>) f.donateFilter();
                //Log.d(LOG_TAG, "Cat: D");
            }
            
            coordinator.checkMatch(item);
            //if ( item.getLocation() != null ){
            //	Log.d("debugging", "Name "+item.getName()+", "+item.getLocation().getLocality().toString());
             //   
            //}
            
	        intent.putExtra("cs2340.g21.wms.coordinator", coordinator);
	        intent.putExtra("items", i);
	        intent.putExtra("original", (ArrayList<Item>)coordinator.getUser().getItems());
	        intent.setClass(CreateItemActivity.this, ItemListActivity.class);
	        

	        startActivity(intent);
	        finish();
	        
    	}

    }
    
    public void cancelCreate(View view){
        Intent intent = new Intent();
        intent.putExtra("cs2340.g21.wms.coordinator", coordinator);
        intent.putExtra("items", (ArrayList<Item>)coordinator.getUser().getItems());
        intent.putExtra("original", (ArrayList<Item>)coordinator.getUser().getItems());
        intent.setClass(CreateItemActivity.this, ItemListActivity.class);
        startActivity(intent);
        finish();
    }
    
    @Override
    public void onBackPressed() {
        Intent intent = new Intent();
        intent.putExtra("cs2340.g21.wms.coordinator", coordinator);
        intent.setClass(CreateItemActivity.this, HomeScreenActivity.class);
        startActivity(intent);
        finish();
    }
    
    
    private void enableLocationSettings() {
        Intent settingsIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
        startActivity(settingsIntent);
    }
    
    /**
     * Checks to see if an intent can be performed by the device
     * 
     * @param context
     * @param action
     * @return
     */
    public static boolean isIntentAvailable(Context context, String action) {
        final PackageManager packageManager = context.getPackageManager();
        final Intent intent = new Intent(action);
        List<ResolveInfo> list =
                packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
        return list.size() > 0;
    }
    
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
        if (requestCode == CAMERA_REQUEST && resultCode == RESULT_OK) {  
            Bitmap photo = (Bitmap) data.getExtras().get("data");
            //Log.w(LOG_TAG, "Photo Changed2");
            if (photo != null) {
	            mPhotoView.setImageBitmap(photo);
	            mPicture = new SerializableBitmap();
	            mPicture.setBitmap(photo);
	            //Log.w(LOG_TAG, "Photo Changed");
            }
        }
        else if (requestCode == REQ_CODE_PICK_IMAGE) {
            if(resultCode == RESULT_OK){  
                Uri selectedImage = data.getData();
                Bitmap photo;
				try {
					photo = decodeUri(selectedImage);
					mPhotoView.setImageBitmap(photo);
    	            mPicture = new SerializableBitmap();
    	            mPicture.setBitmap(photo);
				} catch (FileNotFoundException e) {
					e.printStackTrace();
				}
            }
        }
        else {
        	//Log.w(LOG_TAG, "Photo Invalid");
        }
    }
    
    /**
     * Method used to scale an image that is chosen from the gallery
     * 
     * @param selectedImage
     * @return scaled image (Bitmap)
     * @throws FileNotFoundException
     */
    private Bitmap decodeUri(Uri selectedImage) throws FileNotFoundException {

        // Decode image size
        BitmapFactory.Options o = new BitmapFactory.Options();
        o.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o);

        // The new size we want to scale to
        final int REQUIRED_SIZE = 140;

        // Find the correct scale value. It should be the power of 2.
        int width_tmp = o.outWidth, height_tmp = o.outHeight;
        int scale = 1;
        while (true) {
            if (width_tmp / 2 < REQUIRED_SIZE
               || height_tmp / 2 < REQUIRED_SIZE) {
                break;
            }
            width_tmp /= 2;
            height_tmp /= 2;
            scale *= 2;
        }

        // Decode with inSampleSize
        BitmapFactory.Options o2 = new BitmapFactory.Options();
        o2.inSampleSize = scale;
        return BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o2);

    }
    
    private void addToTags(String tags) {
    	if (tags != null) {
	    	String newTags = "";
			for (int i=0; i<tags.length(); i++) {
				if (tags.charAt(i) != '#') {
					newTags += tags.charAt(i);
				}
			}
			String[] tagArray = newTags.split(",");
			for(String item:tagArray) {
				if (item.length() != 0) {
					mTags.add(item.trim());
				}
			}
    	}
    	mTags.add(mName);
    }
    
    protected void onPause(){
        super.onPause(coordinator);
    }
    
    
    @Override
    protected void onRestoreInstanceState(Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        // Read values from the "savedInstanceState"-object and put them in your textview
        mPicture = (SerializableBitmap) savedInstanceState.get("image");
        if (mPicture != null) {
        	mPhotoView.setImageBitmap(mPicture.getBitmap());
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        // Save the values you need from your textview into "outState"-object
    	outState.putSerializable("image", mPicture);
        super.onSaveInstanceState(outState);
    }

}
